Package net.sf.tomcatmanager

Source Code of net.sf.tomcatmanager.Controller$ServerStatusLoop

package net.sf.tomcatmanager;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import net.sf.tomcatmanager.MainView.YesNoCancel;
import net.sf.tomcatmanager.Model.ServerState;

/**
* This class represents the controller, which acts upon the model and views.
*
* @author Martin Edling Andersson, Leonard van Driel
*/
public class Controller {

  private static final transient Logger logger = Logger.getLogger(Controller.class.toString());

  private static final int POST_STOP_WAIT_SECONDS = 5;

  // model-view-controller
  private Model model;
  private MainView mainView;
  private PreferencesView preferencesView;
  private LogView logView;
  private ViewHelper viewHelper;

  private Preferences preferences;
  private ScriptRunner startRunner;
  private ScriptRunner stopRunner;

  /**
   * This inner class runs the server status loop, which checks whether the
   * server is running by opening a stream to the server's URL.
   */
  private class ServerStatusLoop implements Runnable {
    public void run() {
      logger.fine("Starting server status loop");
      while (true) {
        boolean connected = false;
        try {
          URL url = new URL("http", model.getServerUrl(), model.getServerPort(), "");
          URLConnection connection = url.openConnection();
          connection.connect();
          connected = true;
        } catch (Exception e) {
        }
        model.setServerStarted(connected);
        try {
          Thread.sleep(model.getSleepTime());
        } catch (InterruptedException e) {
          logger.warning("Server status loop was interrupted: " + e);
          break;
        }
      }
    }
  }

  /**
   * This inner class runs the execution of a bash script for starting and
   * stopping the server.
   */
  private class ScriptRunner {
    private String scriptParam;
    private ServerState failState;
    private Process process;

    public ScriptRunner(String scriptParam, ServerState failState) {
      this.scriptParam = scriptParam;
      this.failState = failState;
    }

    public void run() {
      stopScriptProcess();

      ProcessBuilder builder = new ProcessBuilder();
      builder.command("/bin/sh", "-c", model.getCatalinaScriptFile() + " " + scriptParam);
      builder.environment().put(model.getJavaHomeEnvironmentVariable(), model.getJavaHomePath());
      builder.environment().put(model.getTomcatLocationEnvironmentVariable(), model.getTomcatLocationPath());
      builder.directory(new File(model.getTomcatLocationPath()));
      builder.redirectErrorStream(true);

      try {
        process = builder.start();
      } catch (IOException e) {
        logger.warning("Unable to run process: " + e);
        if (mainView != null) {
          mainView.showWarning("The server could not be started, please check the preferences.",
              "Server could not be started");
        }
        setServerState(failState);
        stopScriptProcess();
      }

      if (process != null) {
        OutputStream stream;
        if (logView != null) {
          stream = logView.getLogOutputStream();
        } else {
          stream = System.out;
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));
        try {
          for (String s = reader.readLine(); s != null; s = reader.readLine()) {
            writer.write(s + "\n");
            writer.flush();
            if (Thread.interrupted()) {
              logger.warning("Read process stream loop was interupted");
              break;
            }
          }
        } catch (IOException e) {
        }
        stopScriptProcess();
      }
    }

    public synchronized void stopScriptProcess() {
      if (process != null) {
        process.destroy();
        process = null;
      }
    }

    public synchronized boolean isScriptRunning() {
      return process != null;
    }
  }

  /**
   * A rather empty constructor.
   */
  public Controller() {
    logger.setLevel(TomcatManagerGui.DEFAULT_LOG_LEVEL);
    preferences = Preferences.userNodeForPackage(getClass());
  }

  /**
   * Setup the java logging facility by lowering the console handler level and
   * adding a file handler.
   */
  public void postInit() {
    // open up all handlers, to allow fine logs to come through
    for (Handler handler : Logger.getLogger("").getHandlers()) {
      handler.setLevel(Level.ALL);
    }
    model.updateLogPath();
    logger.info(About.NAME + " loaded");
  }

  /**
   * Resets all the application's preferences.
   */
  public void resetAllPreferences() {
    logger.fine("Resetting all preferences");
    try {
      if (preferences.nodeExists("")) {
        preferences.removeNode();
      }
    } catch (BackingStoreException e) {
      logger.warning("Unable to reset preferences: " + e);
      if (mainView != null) {
        mainView.showWarning("The preferences could not be reset, please investigate the application log.",
            "Preferences could not be reset");
      }
    }
    preferences = Preferences.userNodeForPackage(getClass());
    model.loadFromPreferences();
    if (mainView != null) {
      mainView.loadFromPreferences();
    }
    if (logView != null) {
      logView.loadFromPreferences();
    }
  }

  private void saveAllPreferences() {
    if (preferencesView != null) {
      preferencesView.saveToModel();
    }
    if (mainView != null) {
      mainView.saveToPreferences();
    }
    if (logView != null) {
      logView.saveToPreferences();
    }
    model.saveToPreferences();
    try {
      preferences.flush();
    } catch (BackingStoreException e) {
      logger.warning("Unable to store main view state: " + e);
      if (mainView != null) {
        mainView.showWarning("The preferenes could not be saved, please investigate the application log.",
            "The preferenes could not be saved");
      }
    }
  }

  private void hideAll() {
    if (preferencesView != null) {
      preferencesView.setVisible(false);
    }
    if (mainView != null) {
      mainView.setVisible(false);
    }
    if (logView != null) {
      logView.setVisible(false);
    }
    if (viewHelper != null) {
      viewHelper.getRestartAction().setEnabled(false);
      viewHelper.getShowLogAction().setEnabled(false);
      viewHelper.getShowManagerAction().setEnabled(false);
      viewHelper.getStatusAction().setEnabled(false);
    }
  }

  /**
   * Initiates periodical server status checking by running a server status
   * loop class.
   */
  public void startServerStatusLoop() {
    ServerStatusLoop messageLoop = new ServerStatusLoop();
    new Thread(messageLoop).start();
  }

  /**
   * Starts the server by running a script runner on the startup script.
   */
  public void startServer(boolean runInThread) {
    logger.info("Starting up server");
    setServerState(ServerState.STARTING);
    Runnable runnable = new Runnable() {
      public void run() {
        if (startRunner != null) {
          startRunner.stopScriptProcess();
        }
        if (stopRunner != null) {
          stopRunner.stopScriptProcess();
        }
        startRunner = new ScriptRunner(model.getStartupScriptParam(), ServerState.STARTING_FAILED);
        startRunner.run();
      }
    };
    if (runInThread) {
      new Thread(runnable).start();
    } else {
      runnable.run();
    }
  }

  /**
   * Stops the server by running a script runner on the shutdown script.
   */
  public void stopServer(boolean runInThread) {
    logger.info("Shutting down server");
    setServerState(ServerState.STOPPING);
    Runnable runnable = new Runnable() {
      public void run() {
        if (stopRunner != null) {
          stopRunner.stopScriptProcess();
        }
        stopRunner = new ScriptRunner(model.getShutdownScriptParam(), ServerState.STOPPING_FAILED);
        stopRunner.run();
        if (startRunner != null) {
          for (int i = 0; i < POST_STOP_WAIT_SECONDS && startRunner.isScriptRunning(); i++) {
            try {
              Thread.sleep(1000);
            } catch (InterruptedException e) {
              logger.warning("Server stop was interrupted: " + e);
              break;
            }
          }
          startRunner.stopScriptProcess();
        }
      }
    };
    if (runInThread) {
      new Thread(runnable).start();
    } else {
      runnable.run();
    }
  }

  /**
   * Stops the server by running a script runner on the shutdown script.
   */
  public void restartServer(boolean runInThread) {
    logger.info("Restarting server");
    Runnable runnable = new Runnable() {
      public void run() {
        stopServer(false);
        startServer(false);
      }
    };
    if (runInThread) {
      new Thread(runnable).start();
    } else {
      runnable.run();
    }
  }

  private void forceAllStop() {
    if (startRunner != null) {
      startRunner.stopScriptProcess();
    }
    if (stopRunner != null) {
      stopRunner.stopScriptProcess();
    }
  }

  public void toggleServer() {
    switch (model.getServerState()) {
    case STARTED:
    case STOPPING_FAILED:
      stopServer(true);
      break;
    case STOPPED:
    case STARTING_FAILED:
      startServer(true);
      break;
    default:
      break;
    }
  }

  public void setServerState(ServerState serverState) {
    if (model.getServerState() != serverState) {
      model.setServerState(serverState);
      if (mainView != null) {
        mainView.updateServerState(serverState);
      }
    }
  }

  /**
   * Asks the user for confirmation if needed, then quits.
   */
  public void tryQuit() {
    YesNoCancel shouldStop = YesNoCancel.NO;
    if (model.isServerStartedOrAboutTo() && mainView != null) {
      shouldStop = mainView.askToStop();
    }
    if (shouldStop != YesNoCancel.CANCEL) {
      doQuit(shouldStop == YesNoCancel.YES, true);
    }
  }

  /**
   * Stores some program state and quits the application.
   *
   * Assumes running in Swing thread
   */
  private void doQuit(boolean stopServer, boolean runInThread) {
    hideAll();
    Runnable runnable = new Runnable() {
      private boolean stop;

      public void run() {
        if (stop) {
          stopServer(false);
        }
        saveAllPreferences();
        if (model.isServerStoppedOrAboutTo()) {
          forceAllStop();
        }
        logger.info(About.NAME + " exit");
        System.exit(0);
      }

      public Runnable set(boolean stop) {
        this.stop = stop;
        return this;
      }
    }.set(stopServer);
    if (runInThread) {
      new Thread(runnable).start();
    } else {
      runnable.run();
    }
  }

  public Model getModel() {
    return model;
  }

  public void setModel(Model model) {
    this.model = model;
  }

  public Preferences getPreferences() {
    return preferences;
  }

  public MainView getMainView() {
    return mainView;
  }

  public void setMainView(MainView mainView) {
    this.mainView = mainView;
  }

  public LogView getLogView() {
    return logView;
  }

  public void setLogView(LogView logView) {
    this.logView = logView;
  }

  public void setPreferencesView(PreferencesView preferencesView) {
    this.preferencesView = preferencesView;
  }

  public ViewHelper getViewHelper() {
    return viewHelper;
  }

  public void setViewHelper(ViewHelper viewHelper) {
    this.viewHelper = viewHelper;
  }

}
TOP

Related Classes of net.sf.tomcatmanager.Controller$ServerStatusLoop

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.